#coding=utf-8
import redis,json
from datetime import timedelta
from settings import REDIS_SETTING,REDIS_PREFIX
from core.ViewMaker import DataEncoder

class RedisManager(object):
    _pool = {}
    _lock = True
    @staticmethod
    def _init(key):
        conf = REDIS_SETTING.get(key)
        if conf is None:
            raise Exception('cannot init redis %s' % key)
        init_data = {}
        init_data['host'] = conf['host']
        init_data['port'] = conf['port']
        init_data['db'] = conf['db']
        if conf.get('pass'):
            init_data['password'] = conf['pass']
        RedisManager._pool[key] = redis.ConnectionPool(**init_data)

    @staticmethod
    def init():
        for each in REDIS_SETTING.keys():
            RedisManager._init(each)

    @staticmethod
    def connect(key):
        return redis.Redis(connection_pool=RedisManager._pool[key])

    @staticmethod
    def set(conn_name,name,value,time):
        r = RedisManager.connect(conn_name)
        return r.setex(name,value,time)

    @staticmethod
    def get(conn_name,name):
        r = RedisManager.connect(conn_name)
        return r.get(name)

    @staticmethod
    def delete(conn_name,name):
        r = RedisManager.connect(conn_name)
        return r.delete(name)

    @staticmethod
    def cache_wrapper(time):
        if not isinstance(time, timedelta):
            raise Exception('time param must be a timedelta object')
        def wrapper_func(func):
            def innerfunc(*args):
                funcname = func.__name__
                postfix = '_'.join([str(n) for n in args])
                cache_key = '__'.join([REDIS_PREFIX,funcname,postfix])
                cache_data = RedisManager.get('memory',cache_key)
                if cache_data is None:
                    new_data = func(*args)
                    if new_data:
                        RedisManager.set('memory',cache_key,json.dumps(new_data,ensure_ascii=False, cls=DataEncoder),time)
                    return new_data
                else:
                    return json.loads(cache_data)
            return innerfunc
        return wrapper_func
